<template>
  <div>
    <q-layout>
      <q-layout-header ref="header">
        <xheader :title="pageInfo.page.NAME" show-filter :is-filter="isFilter"
                 @click-filter="popupFilter"></xheader>
      </q-layout-header>
      <q-page-container>

        <q-page>
          <q-tabs position="top" ref="tab" v-model="tabIndex"
                  v-if="pageInfo.page.CHART_TYPE && pageInfo.page.CHART_TYPE !== null">
            <!-- 选项卡 - 注意slot="title" -->
            <q-tab default slot="title" label="表格" name="grid" @select="showGrid"/>
            <q-tab slot="title" label="柱状图" name="bar" @select="showBar"
                   v-if="isShowBarTab"/>
            <q-tab slot="title" label="饼图" name="pie" @select="showPie"
                   v-if="isShowPieTab"/>
            <q-tab slot="title" label="折线图" name="line" @select="showLine"
                   v-if="isShowLineTab"/>
          </q-tabs>
          <div v-show="tabIndex === 'grid'">
            <xscrollarea :scroll-height="gridScrollHeight">
              <q-table
                :data="data.data"
                :columns="pageInfo.columns"
                :loading="loading"
                dense
                separator="cell"
                :pagination="{page:1,rowsPerPage:20}"
                hide-bottom
                row-key="name"
              >
              </q-table>
            </xscrollarea>
          </div>
          <div v-show="tabIndex === 'bar'">
            <xscrollarea :scroll-height="scrollHeight">
              <canvas ref="bar" class="fit"></canvas>
            </xscrollarea>
          </div>
          <div v-show="tabIndex === 'pie'">
            <xscrollarea :scroll-height="scrollHeight">
              <canvas ref="pie" class="fit"></canvas>
            </xscrollarea>
          </div>
          <div v-show="tabIndex === 'line'">
            <xscrollarea :scroll-height="scrollHeight">
              <canvas ref="line" class="fit"></canvas>
            </xscrollarea>
          </div>
        </q-page>

      </q-page-container>
      <q-layout-footer>
        <div ref="footer" v-show="tabIndex === 'grid'">
          <q-pagination @input="pageChange" v-model="pageNum" :max-pages="9" :min="1" :max="pageCount"
                        boundary-links/>
        </div>
      </q-layout-footer>
    </q-layout>
    <q-modal v-model="showPopup" position="bottom" @hide="cancel">
      <q-modal-layout>
        <xfilterheader @cancel="cancel" @confirm="search"></xfilterheader>
        <div class="layout-padding">
          <q-input v-for="p in pageInfo.params" v-if="p.TYPE === 'Text' || p.TYPE === 'Number'"
                   :type="p.TYPE === 'Number'?'number':'text'"
                   :float-label="p.NAME" v-model="params[p.CODE]" placeholder="输入" clearable/>
          <q-datetime
            format="YYYY-MM-DD HH:mm:ss"
            format-model="date"
            v-for="p in pageInfo.params"
            v-if="p.TYPE === 'Date' || p.TYPE === 'DateTime' ||p.TYPE === 'Time'||p.TYPE === 'Year'||p.TYPE === 'Month'"
            v-model="params[p.CODE]"
            :float-label="p.NAME" :type="dateFormat(p.TYPE)" clearable/>
          <q-select
            v-for="p in pageInfo.params" v-if="p.TYPE === 'Selector'"
            v-model="params[p.CODE]"
            :float-label="p.NAME"
            :options="optionsFormat(p.JSON_DATA)" clearable
          />
        </div>

      </q-modal-layout>
    </q-modal>
  </div>
</template>

<script>

  import utils from '../../js/utils'
  import { date } from 'quasar'
  import F2 from '@antv/f2'
  import PieLabel from '@antv/f2/lib/plugin/pie-label'
  import Xheader from '../../components/xheader'
  import Xscrollarea from '../../components/xscrollarea'
  import Xfilterheader from '../../components/xfilterheader'

  import { reportLine } from '../../js/mockData'

  export default {
    name: 'report',
    components: { Xfilterheader, Xscrollarea, Xheader },
    data: () => (
      {
        pageInfo: { page: {}, columns: [], params: [] },
        params: {},
        paramsBak: {},
        data: { data: [] },
        showPopup: false,
        loading: false,
        pageNum: 1,
        limit: 20,
        doSearch: false,
        scrollHeight: 0,
        gridScrollHeight: 0,
        tabIndex: 'grid',
        barChart: {},
        pieChart: {},
        lineChart: {}
      }),

    computed: {
      isFilter () {
        for (let p in this.params) {
          if (this.params[p] !== '' && this.params[p] !== null && this.params[p] !== undefined) {
            return true
          }
        }
        return false
      },
      pageCount () {
        return (this.data.total % this.getLimit > 0) ? Math.ceil(this.data.total / this.getLimit) : this.data.total / this.getLimit
      },
      getLimit () {
        // 根据屏幕高度计算一屏可以展示多少条数据，每次分页请求的数据不超过一屏展示
        // 40=表头高度，28的每行数据高度
        return Math.floor((this.gridScrollHeight - 40) / 28)
      },
      isShowBarTab () {
        if (this.pageInfo.page.CHART_TYPE && this.pageInfo.page.CHART_TYPE !== null && this.pageInfo.page.CHART_TYPE.indexOf('bar') !== -1) {
          return true
        }
        return false
      },
      isShowPieTab () {
        if (this.pageInfo.page.CHART_TYPE && this.pageInfo.page.CHART_TYPE !== null && this.pageInfo.page.CHART_TYPE.indexOf('pie') !== -1) {
          return true
        }
        return false
      },
      isShowLineTab () {
        if (this.pageInfo.page.CHART_TYPE && this.pageInfo.page.CHART_TYPE !== null && this.pageInfo.page.CHART_TYPE.indexOf('line') !== -1) {
          return true
        }
        return false
      }
    },
    methods: {
      getPageInfo () {
        this.axios.post(this.$conf.report_server + '/report/pageInfo', this.$qs.stringify({
          id: this.$route.query.id
        })).then(res => {
          if (res.data.result) {
            this.pageInfo = res.data
            this.transCol()
            this.transParams()
            this.$nextTick(() => {
              this.getData()
            })
            this.popupMessage()
          }
        })
      },
      getData () {
        this.loading = true
        let query = { id: this.$route.query.id, page: this.pageNum, limit: this.getLimit }
        let params = this.submitParams()
        this.axios.post(this.$conf.report_server + '/report/dataList',
          this.$qs.stringify(Object.assign(query, params))).then(res => {
          if (res.data.result) {
            this.data = res.data
            this.clearCharts()
            this.$nextTick(() => {
              this.transData()
              this.loading = false
              this.changeScrollHeight()
            })
          }
        })
      },
      submitParams () {
        let _params = Object.assign({}, this.params)
        let queryParams = ''
        for (let p of this.pageInfo.params) {
          //转换后台可接受的日期格式
          if (p.TYPE === 'Date' || p.TYPE === 'DateTime' || p.TYPE === 'Time' || p.TYPE === 'Year' || p.TYPE === 'Month') {
            _params[p.CODE] = date.formatDate(_params[p.CODE], 'YYYY-MM-DD HH:mm:ss')
          }
          if (_params[p.CODE] !== '' && _params[p.CODE] !== null && _params[p.CODE] !== undefined) {
            queryParams += p.CODE + ','
          }
        }
        return Object.assign({ Query_Params: queryParams }, _params)
      },
      transCol () {
        this.tableAllWidth = 0
        for (let i = 0; i < this.pageInfo.columns.length; i++) {
          let c = this.pageInfo.columns[i]
          c.name = c.COLUMN_NAME
          c.label = c.NAME
          c.field = c.COLUMN_NAME
          c.width = 100
          c.align = 'center'
          this.tableAllWidth += 100
          if (i === 0) {
            c.fixed = true
          }
        }
      },
      transParams () {
        for (let p of this.pageInfo.params) {
          if (p.DEFAULT_VALUE !== '' && p.DEFAULT_VALUE !== null) {
            this.params[p.CODE] = p.DEFAULT_VALUE
          }
        }
      },
      transData () {
        let sm = new Map()
        for (let dd of this.data.data) {
          for (let d in dd) {
            let v = dd[d]
            if (v !== null) {
              let set = sm.get(d)
              if (set === undefined || set === null) {
                set = new Set()
                sm.set(d, set)
              }
              set.add(v)
            }
          }
        }
        // let lengthMap = new Map()
        sm.forEach((value, key, map) => {
          let max = 0
          value.forEach((element, sameElement, set) => {
            let length = utils.strlen(element)
            if (length > max) {
              max = length
            }
          })
          // lengthMap.set(key, max)

          for (let i = 0; i < this.pageInfo.columns.length; i++) {
            let c = this.pageInfo.columns[i]
            if (c.key === key) {
              c.width = max * 5
              break
            }
          }
        })
      },
      popupFilter () {
        this.showPopup = true
        this.doSearch = false
        for (let p in this.params) {
          this.paramsBak[p] = this.params[p]
        }
      },
      search () {
        this.showPopup = false
        this.doSearch = true
        this.data = []
        this.getData()
      },
      cancel () {
        this.showPopup = false
        if (!this.doSearch) {
          for (let p in this.params) {
            if (this.paramsBak[p] !== undefined) {
              this.params[p] = this.paramsBak[p]
            } else {
              this.params[p] = ''
            }
          }
        }
      },
      dateFormat (type) {
        if (type === 'Date') {
          return 'date'
        } else if (type === 'DateTime') {
          return 'datetime'
        } else if (type === 'Time') {
          return 'time'
        } else if (type === 'Year') {
          return 'date'
        } else if (type === 'Month') {
          return 'date'
        } else {
          return 'date'
        }
      },
      optionsFormat (json) {
        // let arr = eval(json)
        let rArr = []
        if (json !== null && json !== '') {
          let arr = eval(json)
          for (let a of arr) {
            rArr.push({ value: a.value, label: a.name })
          }
        }
        return rArr
      },
      popupMessage () {
        if (this.tableAllWidth > this.$parent.webWidth) {
          this.$parent.tip('可左右滑动查看数据', 3000, 'top')
        }
      },
      pageChange (pageNum) {
        if (pageNum && pageNum > 0 && pageNum <= this.pageCount) {
          this.pageNum = pageNum
          this.getData()
        }
      },
      showGrid () {
      },
      showBar () {
        if (Object.keys(this.barChart).length === 0) {
          if (this.data.data && this.data.data.length) {
            this.barChart = new F2.Chart({
              el: this.$refs.bar,
              pixelRatio: window.devicePixelRatio // 指定分辨率
            })
            let data = this.transBarData()
            this.barChart.source(data.list)
            this.barChart.tooltip({
              showItemMarker: false,
              onShow (ev) {
                let items = ev.items
                items[0].name = data.nameName + '(' + items[0].name + ')'
                items[0].value = data.valueName + '(' + items[0].value + ')'
              }
            })
            this.barChart.coord({
              transposed: true
            })
            this.barChart.axis('name', {
              line: F2.Global._defaultAxis.line,
              grid: null
            })
            this.barChart.axis('value', {
              line: null,
              grid: F2.Global._defaultAxis.grid,
              label: (text, index, total) => {
                let textCfg = {}
                if (index === 0) {
                  textCfg.textAlign = 'left'
                } else if (index === total - 1) {
                  textCfg.textAlign = 'right'
                }
                return textCfg
              }
            })
            this.barChart.interval().position('name*value').color('name', this.pageInfo.page.CHART_COLOR ? this.pageInfo.page.CHART_COLOR.split(',') : undefined)
            this.barChart.render()
          }
        } else {
          this.barChart.repaint()
        }
      },
      showPie () {
        if (Object.keys(this.pieChart).length === 0) {
          if (this.data.data && this.data.data.length) {
            this.pieChart = new F2.Chart({
              el: this.$refs.pie,
              pixelRatio: window.devicePixelRatio,
              plugins: PieLabel
            })
            let data = this.transPieData()
            this.pieChart.source(data.list)
            this.pieChart.coord('polar', {
              transposed: true,
              innerRadius: 0.4,
              radius: 0.75
            })
            this.pieChart.axis(false)
            this.pieChart.legend({
              position: 'bottom',
              align: 'center'
            })
            this.pieChart.tooltip(false)
            let sum = 0
            data.list.map(function (obj) {
              sum += obj.value
            })
            this.pieChart.guide().text({
              position: ['50%', '50%'],
              content: sum,
              style: {
                fontSize: 24
              }
            })
            let _d = data
            // 配置文本饼图
            this.pieChart.pieLabel({
              sidePadding: 5,
              skipOverlapLabels: false,
              activeShape: true,
              label1 (data) {
                return {
                  text: data.name,
                  fill: '#808080'
                }
              },
              label2 (data) {
                return {
                  fill: '#000000',
                  text: _d.valueName + ':' + data.value,
                  fontWeight: 500,
                  fontSize: 10
                }
              }
            })

            this.pieChart.interval().position('const*value').color('name', this.pageInfo.page.CHART_COLOR ? this.pageInfo.page.CHART_COLOR.split(',') : undefined).adjust('stack')
            this.pieChart.render()
          }
        } else {
          this.pieChart.repaint()
        }
      },
      showLine () {
        if (Object.keys(this.lineChart).length === 0) {
          if (this.data.data && this.data.data.length) {
            this.lineChart = new F2.Chart({
              el: this.$refs.line,
              pixelRatio: window.devicePixelRatio, // 指定分辨率
              padding: ['auto', 'auto', 90, 'auto']
              //plugins: scrollBar
            })
            let data = this.transLineData()
            if (process.env.NODE_ENV === 'development') {
              //data.list = reportLine
            }
            this.lineChart.source(data.list, { value: { type: 'linear', min: 0 } })
            this.lineChart.tooltip({
              showCrosshairs: true,
              showItemMarker: false,
              onShow (ev) {
                let items = ev.items
                items[0].name = data.nameName + '(' + items[0].title + ')'
                items[0].value = data.valueName + '(' + items[0].value + ')'
              }
            })
            this.lineChart.axis('name', {
              tickLine: {
                lineWidth: 1,
                stroke: '#ccc',
                length: 5,// 刻度线长度
              },
              label: (text, index, total) => {
                let textCfg = {}
                if (index === 0) {
                  textCfg.textAlign = 'left'
                } else if (index === total - 1) {
                  textCfg.textAlign = 'right'
                }

                if (this.isLineLabelRotate(data)) {
                  textCfg.rotate = Math.PI / 3
                  textCfg.textAlign = 'start'
                  textCfg.textBaseline = 'middle'
                }
                return textCfg
              }
            })
            this.lineChart.line().position('name*value')//.color('name', this.pageInfo.page.CHART_COLOR ? this.pageInfo.page.CHART_COLOR.split(',') : undefined)
            this.lineChart.point().position('name*value').style({
              stroke: '#fff',
              lineWidth: 1
            })
            /*this.lineChart.interaction('pan');
            // 定义进度条
            this.lineChart.scrollBar({
              mode: 'x',
              xStyle: {
                offsetY: -5
              }
            });*/
            this.lineChart.render()
          }
        } else {
          this.lineChart.repaint()
        }
      },
      transBarData () {
        return this.transData('bar')
      },
      transPieData () {
        return this.transData('pie')
      },
      transLineData () {
        return this.transData('line')
      },
      transData (type) {
        let data = {}
        let list = []
        let nameName = ''
        let valueName = ''
        for (let c of this.pageInfo.columns) {
          if (c.CHART_TYPE && c.CHART_TYPE.indexOf(type) !== -1) {
            if (c.CHART_AXIS === 'name') {
              nameName = c.COLUMN_NAME
              data.nameName = c.NAME
            } else if (c.CHART_AXIS === 'value') {
              valueName = c.COLUMN_NAME
              data.valueName = c.NAME
            }
          }
        }
        for (let dd of this.data.data) {
          list.push({ const: 'const', name: dd[nameName], value: dd[valueName] })
        }
        data.list = list
        return data
      },
      changeScrollHeight () {
        this.scrollHeight = this.$parent.webHeight - this.$refs.header.$el.clientHeight -
          (this.$refs.tab ? this.$refs.tab.$el.clientHeight : 0)
        this.gridScrollHeight = this.scrollHeight - this.$refs.footer.clientHeight

      },
      isLineLabelRotate (data) {
        if (data.list.length >= 10) {
          return true
        }
        let allNameLength = 0
        for (let i of data.list) {
          allNameLength += i.name.length
        }
        if (allNameLength > 50) {
          return true
        }
      },
      clearCharts () {
        this.barChart = {}
        this.pieChart = {}
        this.lineChart = {}
      }
    },
    mounted () {
      this.getPageInfo()
    },
    created () {

    }
  }
</script>

<style scoped>

</style>
